package cn.jingsheng.backup.bean;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.jingsheng.backup.util.DbUtil;
import cn.jingsheng.backup.util.SystemConfig;

/**
 * 分页信息
 * 
 * @author 李晓丹
 * 
 */
public class PagedListInfo {
	/**
	 * 日志记录
	 */
	private static Log log = LogFactory.getLog(PagedListInfo.class);
	// 起始行
	private int startNum = 1;
	// 单页行
	private int countOfPage = Integer.valueOf(SystemConfig.getProperties("PagedListInfo_countOfPage", "15"));
	// 总行数
	private int total;
	private LinkedList<String> orderBy = new LinkedList<String>();
	// 排列顺序
	private HashMap<String, String> ascOrDesc = new HashMap<String, String>();

	public HashMap<String, String> getAscOrDesc() {
		return ascOrDesc;
	}

	/**
	 * 获取字段对应排列顺序
	 * 
	 * @param col
	 *            字段
	 * @return
	 */
	public String getAscOrDesc(String col) {
		String sort = ascOrDesc.get(col);
		if (sort == null) {
			sort = "asc";
			ascOrDesc.put(col, sort);
		}
		return sort;
	}

	public void setAscOrDesc(HashMap<String, String> ascOrDesc) {
		this.ascOrDesc = ascOrDesc;
	}

	public int getStartNum() {
		return startNum;
	}

	public void setStartNum(int startNum) {
		this.startNum = startNum;
	}

	public int getCountOfPage() {
		return countOfPage;
	}

	public void setCountOfPage(int countOfPage) {
		this.countOfPage = countOfPage;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public LinkedList<String> getOrderBy() {
		return orderBy;
	}

	public void setOrderBy(LinkedList<String> orderBy) {
		this.orderBy = orderBy;
	}

	/**
	 * 下一页
	 * 
	 * @return
	 */
	public int forwordPage() {
		int forword = this.currentPage() + 1;
		return forword > lastPage() ? lastPage() : forword;
	}

	/**
	 * 当前页
	 * 
	 * @return
	 */
	public int currentPage() {
		return this.startNum / this.countOfPage;
	}

	/**
	 * 尾页
	 * 
	 * @return
	 */
	public int lastPage() {
		int last = this.total / this.countOfPage;
		if (this.total % this.countOfPage != 0) {
			last++;
		}
		return last;
	}

	/**
	 * 上一页
	 * 
	 * @return
	 */
	public int backwordPage() {
		int backword = this.currentPage() - 1;
		return backword < 1 ? 0 : backword;
	}

	/**
	 * 设置字段排列顺序
	 * 
	 * @param sort
	 *            字段
	 * @param ad
	 *            排列方向
	 */
	public void sortBy(String sort, String ad) {
		if (sort != null) {
			orderBy.remove(sort);
			orderBy.addFirst(sort);
			ascOrDesc.put(sort, ad);
		}
		ascOrDesc.put(sort, "asc".equals(ad) ? "desc" : "asc");
	}

	/**
	 * 生成分页SQL
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            查询参数
	 */
	public void process(StringBuilder sql, Object[] params) {
		this.queryCount(sql.toString(), params);
		String driver = DbUtil.DRIVER_CLASS;
		if (driver.equals("oracle.jdbc.driver.OracleDriver")) {
			processOracle(sql, params);
		} else if (driver.equals("com.mysql.jdbc.Driver")) {
			processMysql(sql, params);
		}
	}

	/**
	 * 生成分页SQL Oracle
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            查询参数
	 */
	private void processOracle(StringBuilder sql, Object[] params) {
		sql.insert(0, "WITH TMP_TABLE AS(\n");
		if (orderBy.size() > 0) {
			sql.append(" order by ");
		}
		for (int i = 0; orderBy != null && i != orderBy.size(); i++) {
			sql.append(i == 0 ? "" : ",");
			sql.append(orderBy.get(i));
			sql.append(" ");
			String sort = ascOrDesc.get(orderBy.get(i));
			sql.append(sort == null ? "asc" : sort);
		}
		sql.append(")SELECT * FROM(\n");
		sql.append("SELECT A.*, ROWNUM TMP__ROWNUM__\n");
		sql.append("FROM TMP_TABLE A\n");
		sql.append("WHERE ROWNUM <= ");
		sql.append(this.startNum + this.countOfPage - 1);
		sql.append(")WHERE TMP__ROWNUM__ >= ");
		sql.append(this.startNum);

	}

	/**
	 * 生成分页SQL Mysql
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            查询参数
	 */
	private void processMysql(StringBuilder sql, Object[] params) {
		if (orderBy.size() > 0) {
			sql.append(" order by ");
		}
		for (int i = 0; orderBy != null && i != orderBy.size(); i++) {
			sql.append(i == 0 ? "" : ",");
			sql.append(orderBy.get(i));
			sql.append(" ");
			String sort = ascOrDesc.get(orderBy.get(i));
			sql.append(sort == null ? "asc" : sort);
		}
		sql.append(" LIMIT ");
		sql.append(this.startNum += this.startNum <= 0 ? 0 : -1);
		sql.append(",");
		sql.append(this.countOfPage - 1);

	}

	/**
	 * 获取查询结果集总行数
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            查询参数
	 */
	private void queryCount(String sql, Object[] params) {
		ResultSet rs = null;
		PreparedStatement ps = DbUtil.prepareStatement("select count(*) as total from (" + sql + ") TMP", params);
		try {
			rs = ps.executeQuery();
			while (rs.next()) {
				// 总行数赋值
				this.setTotal(rs.getInt("total"));
			}
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			DbUtil.close(rs);
			DbUtil.close(ps);
		}
	}
}
